//: A UIKit based Playground for presenting user interface
  
import UIKit
import PlaygroundSupport

typealias Filter = (CIImage) -> CIImage

func blur(radius: Double) -> Filter {
    return { image in
        let parameters: [String : Any] = [
            kCIInputRadiusKey: radius,
            kCIInputImageKey: image
        ]
        guard let filter = CIFilter(name: "CIGaussianBlur", parameters: parameters) else { fatalError() }
        guard let outputImage = filter.outputImage else { fatalError() }
        return outputImage
    }
}

/// 颜色生成滤镜 (CIConstantColorGenerator)
func generate(color: UIColor) -> Filter {
    return { _ in
        let parameters = [kCIInputColorKey: CIColor(cgColor: color.cgColor)]
        guard let filter = CIFilter(name: "CIConstantColorGenerator", parameters: parameters) else { fatalError() }
        guard let outputImage = filter.outputImage else { fatalError() }
        return outputImage
    }
}

/// 图像覆盖合成滤镜 (CISourceOverCompositing)
func compositeSourceOver(overlay: CIImage) -> Filter {
    return { image in
        let parameters = [
            kCIInputBackgroundImageKey: image,
            kCIInputImageKey: overlay
        ]
        guard let filter = CIFilter(name: "CISourceOverCompositing", parameters: parameters) else { fatalError() }
        guard let outputImage = filter.outputImage else { fatalError() }
        return outputImage.cropped(to: image.extent)
    }
}

func overlay(color: UIColor) -> Filter {
    return { image in
        let overlay = generate(color: color)(image).cropped(to: image.extent)
        return compositeSourceOver(overlay: overlay)(image)
    }
}

func compose(filter filter1: @escaping Filter, with filter2: @escaping Filter) -> Filter {
    return { image in filter2(filter1(image)) }
}

infix operator >>>

func >>>(filter1: @escaping Filter, filter2: @escaping Filter) -> Filter {
    return { image in filter2(filter1(image)) }
}


class MyViewController : UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        let imageView = UIImageView(frame: view.bounds)
//        imageView.backgroundColor = .red
        view.addSubview(imageView)

        let url = URL(string: "http://qjd-images.oss-cn-hangzhou.aliyuncs.com/18-9-30/6799266.jpg")!
        let image = CIImage(contentsOf: url)!

        let radius = 1.0
        let color = UIColor.red.withAlphaComponent(0.2)
        let blurredImage = blur(radius: radius)(image)
        let overlaidImage = overlay(color: color)(blurredImage)

        let result = overlay(color: color)(blur(radius: radius)(image))

        let blurAndOverlay = compose(filter: blur(radius: radius), with: overlay(color: color))
        let result1 = blurAndOverlay(image)

        let blurAndOverlay2 = blur(radius: radius) >>> overlay(color: color)
        let result2 = blurAndOverlay2(image)

        imageView.image = UIImage(ciImage: result2)
    }
}


// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
